home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_300
/
346_02
/
m16mch.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-02-08
|
12KB
|
727 lines
/* M16MCH:C */
/*
* (C) Copyright 1991
* All Rights Reserved
*
* Alan R. Baldwin
* 721 Berkeley St.
* Kent, Ohio 44240
*/
#include <stdio.h>
#include <setjmp.h>
#include "asm.h"
#include "m6816.h"
#define NB 256
int *bp;
int bm;
int bb[NB];
/*
* Process a machine op.
*/
VOID
machine(mp)
struct mne *mp;
{
register op, rf, cpg;
struct expr e1, e2, e3;
char id[NCPS];
struct area *espa;
int c, pc, t1, t2, vn;
pc = dot.s_addr;
cpg = 0;
op = mp->m_valu;
switch (rf = mp->m_type) {
case S_SDP:
e1.e_mode = 0;
e1.e_flag = 0;
e1.e_addr = 0;
e1.e_base.e_ap = NULL;
espa = NULL;
if (more()) {
expr(&e1, 0);
if (e1.e_flag == 0 && e1.e_base.e_ap == NULL) {
if (e1.e_addr) {
err('b');
}
}
if ((c = getnb()) == ',') {
getid(id, -1);
espa = alookup(id);
if (espa == NULL) {
err('u');
}
} else {
unget(c);
}
}
if (espa) {
outdp(espa, &e1);
} else {
outdp(dot.s_area, &e1);
}
lmode = SLIST;
break;
case S_IMMA:
if (addr(&e1) == T_IMM) {
if (mchimm(&e1)) {
outab(PAGE3);
outab(op);
outrw(&e1, R_NORM);
} else {
outab(op);
outrb(&e1, R_NORM);
}
} else {
dot.s_addr += 4;
aerr();
}
break;
case S_IM16:
if (addr(&e1) == T_IMM) {
outab(PAGE3);
outab(op);
outrw(&e1, R_NORM);
} else {
dot.s_addr += 4;
aerr();
}
break;
case S_BIT:
t1 = addr(&e1);
comma();
t2 = addr(&e2);
if ((t2 != T_IMM) && (t2 != T_EXT)) {
aerr();
}
if (t1 == T_EXT) {
outab(op|0x30);
mchubyt(&e2);
outrb(&e2, R_USGN);
outrw(&e1, R_NORM);
} else
if (t1 & T_INDX) {
if (mchindx(t1, &e1)) {
outab(op|(t1 & 0x30));
mchubyt(&e2);
outrb(&e2, R_USGN);
outrw(&e1, R_NORM);
} else {
outab(PAGE1);
outab(op|(t1 & 0x30));
mchubyt(&e2);
outrb(&e2, R_USGN);
mchubyt(&e1);
outrb(&e1, R_USGN);
}
} else {
dot.s_addr += 4;
aerr();
}
break;
case S_BITW:
t1 = addr(&e1);
comma();
t2 = addr(&e2);
if ((t2 != T_IMM) && (t2 != T_EXT)) {
aerr();
}
if (t1 == T_EXT) {
t1 |= 0x30;
} else
if (t1 & T_INDX) {
if (t1 & T_IND8) {
aerr();
}
} else {
aerr();
}
outab(PAGE2);
outab(op|(t1 & 0x30));
outrw(&e2, R_NORM);
outrw(&e1, R_NORM);
break;
case S_BRBT:
t1 = addr(&e1);
comma();
t2 = addr(&e2);
comma();
addr(&e3);
if ((t2 != T_IMM) && (t2 != T_EXT)) {
aerr();
}
if (t1 == T_EXT) {
outab(op|0x30);
mchubyt(&e2);
outrb(&e2, R_USGN);
outrw(&e1, R_NORM);
if (mchabs(&e3)) {
vn = e3.e_addr - dot.s_addr - 2;
outaw(vn);
} else {
outrw(&e3, R_PCR);
}
} else
if (t1 & T_INDX) {
if ((t1 & T_IND8) || (t1 & T_IND16)) {
;
} else
if (mchindx(t1, &e1)) {
t1 |= T_IND16;
} else {
if (mchabs(&e3)) {
vn = e3.e_addr - dot.s_addr - 4;
if ((vn < -128) || (vn > 127)) {
t1 |= T_IND16;
} else {
t1 |= T_IND8;
}
} else {
t1 |= T_IND16;
}
}
if (t1 & T_IND8) {
if (op == 0x0A)
op = 0xCB;
if (op == 0x0B)
op = 0x8B;
outab(op|(t1 & 0x30));
mchubyt(&e2);
outrb(&e2, R_USGN);
mchubyt(&e1);
outrb(&e1, R_USGN);
if (mchabs(&e3)) {
vn = e3.e_addr - dot.s_addr - 1;
if ((vn < -128) || (vn > 127))
aerr();
outab(vn);
} else {
outrb(&e3, R_PCR);
}
} else
if (t1 & T_IND16) {
outab(op|(t1 & 0x30));
mchubyt(&e2);
outrb(&e2, R_USGN);
outrw(&e1, R_NORM);
if (mchabs(&e3)) {
vn = e3.e_addr - dot.s_addr - 2;
outaw(vn);
} else {
outrw(&e3, R_PCR);
}
}
} else {
dot.s_addr += 6;
aerr();
}
break;
case S_LDED:
t1 = addr(&e1);
if (t1 == T_EXT) {
outab(PAGE2);
outab(op);
outrw(&e1, R_NORM);
} else {
dot.s_addr += 4;
aerr();
}
break;
case S_MAC:
t1 = addr(&e1);
if (more()) {
comma();
t2 = addr(&e2);
if ((t1 != T_IMM) || !mchabs(&e1) ||
(t2 != T_IMM) || !mchabs(&e2))
aerr();
outab(op);
outab(((e1.e_addr << 4) & 0xF0) | (e2.e_addr & 0x0F));
} else {
if (t1 != T_IMM)
aerr();
outab(op);
outrb(&e1, R_NORM);
}
break;
case S_PSHM:
vn = 0;
do {
if ((t1 = admode(pshm)) == 0 || vn & t1)
aerr();
vn |= t1;
} while (more() && comma());
outab(op);
outab(vn);
break;
case S_PULM:
vn = 0;
do {
if ((t1 = admode(pulm)) == 0 || vn & t1)
aerr();
vn |= t1;
} while (more() && comma());
outab(op);
outab(vn);
break;
case S_JXX:
t1 = addr(&e1);
comma();
t2 = addr(&e2);
if ((t1 != T_IMM) && (t1 != T_EXT)) {
aerr();
}
if (t2 == T_EXT) {
if (op == 0x4B)
outab(0x70);
if (op == 0x89)
outab(0xFA);
mchubyt(&e1);
outrb(&e1, R_USGN);
outrw(&e2, R_NORM);
} else
if ((t2 & T_INDX) && (t2 != (T_INDX|T_IND8))) {
outab(op|(t2 & 0x30));
mchubyt(&e1);
outrb(&e1, R_USGN);
outrw(&e2, R_NORM);
} else {
dot.s_addr += 4;
aerr();
}
break;
case S_MOVB:
case S_MOVW:
t1 = addr(&e1);
comma();
t2 = addr(&e2);
if((t1 == T_EXT) && (t2 == T_EXT)) {
outab(PAGE3);
outab(op|0xFE);
outrw(&e1, R_NORM);
outrw(&e2, R_NORM);
} else
if((t1 & T_INDX) && (t2 == T_EXT)) {
outab(op|(t1 & 0x30));
mchubyt(&e1);
outrb(&e1, R_USGN);
outrw(&e2, R_NORM);
} else
if((t1 == T_EXT) && (t2 & T_INDX)) {
outab(op|0x02|(t2 & 0x30));
mchubyt(&e2);
outrb(&e2, R_USGN);
outrw(&e1, R_NORM);
} else {
dot.s_addr += 6;
aerr();
}
break;
case S_CMP:
case S_LOAD:
case S_STOR:
t1 = addr(&e1);
if (t1 == T_EXT) {
outab(PAGE1);
outab(op|0x30);
outrw(&e1, R_NORM);
} else
if ((t1 == T_IMM) && (rf != S_STOR)) {
outab(PAGE3);
if (rf == S_CMP)
outab(op|0x30);
if (rf == S_LOAD)
outab((op|0x30) & 0xBF);
outrw(&e1, R_NORM);
} else
if (t1 & T_INDX) {
if (mchindx(t1, &e1)) {
outab(PAGE1);
outab(op|(t1 & 0x30));
outrw(&e1, R_NORM);
} else {
outab(op|(t1 & 0x30));
mchubyt(&e1);
outrb(&e1, R_USGN);
}
} else {
dot.s_addr += 4;
aerr();
}
break;
case S_SOPW:
t1 = addr(&e1);
if (t1 == T_EXT) {
t1 |= 0x30;
} else
if (t1 & T_INDX) {
if (t1 & T_IND8) {
aerr();
}
} else {
aerr();
}
outab(PAGE2);
outab(op|(t1 & 0x30));
outrw(&e1, R_NORM);
break;
case S_SOP:
t1 = addr(&e1);
if (t1 == T_EXT) {
outab(PAGE1);
outab(op|0x30);
outrw(&e1, R_NORM);
} else
if (t1 & T_INDX) {
if (mchindx(t1, &e1)) {
outab(PAGE1);
outab(op|(t1 & 0x30));
outrw(&e1, R_NORM);
} else {
outab(op|(t1 & 0x30));
mchubyt(&e1);
outrb(&e1, R_USGN);
}
} else {
dot.s_addr += 4;
aerr();
}
break;
case S_DOPE:
t1 = addr(&e1);
if (t1 == T_EXT) {
outab(PAGE3);
outab(op|0x30);
outrw(&e1, R_NORM);
} else
if (t1 == T_IMM) {
if (op == 0x41) {
if (mchimm(&e1)) {
outab(PAGE3);
outab((op|0x30)&0x3F);
outrw(&e1, R_NORM);
} else {
outab(0x7C);
outrb(&e1, R_NORM);
}
} else {
outab(PAGE3);
outab((op|0x30)&0x3F);
outrw(&e1, R_NORM);
}
} else
if ((t1 & T_INDX) && (t1 != (T_INDX|T_IND8))) {
outab(PAGE3);
outab(op|(t1 & 0x30));
outrw(&e1, R_NORM);
} else {
dot.s_addr += 4;
aerr();
}
break;
case S_DOPD:
t1 = addr(&e1);
if (t1 == T_EXT) {
outab(PAGE3);
outab(op|0x70);
outrw(&e1, R_NORM);
} else
if ((t1 == T_IMM) && (op != 0x8A)) {
if (op == 0x81) {
if (mchimm(&e1)) {
outab(PAGE3);
outab(op|0x30);
outrw(&e1, R_NORM);
} else {
outab(0xFC);
outrb(&e1, R_NORM);
}
} else {
outab(PAGE3);
outab(op|0x30);
outrw(&e1, R_NORM);
}
}